package com.xzlf.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import com.xzlf.service.Cacheservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class HystroxDemoController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private Cacheservice cacheservice;

    /**
     * @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务
    调用问题，使用 Hystrix 容错处理逻辑来处理
     * 属性 fallbackMethod - 如果当前方法调用服务，远程服务出现问题的时候，调
    用本地的哪个方法得到托底数据。
     */
    @GetMapping("/getInfo")
    @HystrixCommand(fallbackMethod = "fallBack", commandProperties = {
            // 默认 20 个;10s 内请求数大于 20 个时就启动熔断器，当请求符合熔断条件时将触发 fallback 逻辑
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD ,value ="5" ),
            // 请求错误率大于 50%时就熔断，然后 for 循环发起请求，当请求符合熔断条件时将触发
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),
            // 默认 5 秒;熔断多少秒后去尝试请求
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000")
    })
    public String getInfo(){
        ServiceInstance choose = loadBalancerClient.choose("application-service");
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange("http://" + choose.getHost()
                + ":" + choose.getPort() + "/", HttpMethod.GET, null, String.class);
        return exchange.getBody();
    }

    public String fallBack(){
        return "Hystrix 服务降级";
    }

    @GetMapping("/testGet")
    public String testGet(){
        return cacheservice.testGet();
    }

    @GetMapping("/testPost")
    public String testPost(){
        return cacheservice.testPost();
    }
}
